<!-- Copyright 2014 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// -->
<!DOCTYPE html>
<title>Unit Test of e2e.ecc.Point</title>
<script src="../../../../closure/base.js"></script>
<script src="test_js_deps-runfiles.js"></script>
<script>
  goog.require('goog.array');
  goog.require('goog.crypt');
  goog.require('goog.testing.jsunit');
  goog.require('e2e.ecc.Ed25519');
  goog.require('e2e.ecc.PrimeCurve');
  goog.require('e2e.ecc.Protocol');
  goog.require('e2e.random');

</script>
<script>
/**
 * Test that basic signing works, using public sources.
 */
var TEST_VECTORS = [
  // https://raw.githubusercontent.com/warner/python-ed25519/master/kat-ed25519.txt
  {
    privateKey:
      '9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60',
    publicKey:
      'd75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a',
    message:
      '',
    signature:
      'e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e06522490155' +
      '5fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b'
  },
  {
    privateKey:
      '4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb',
    publicKey:
      '3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c',
    message:
      '72',
    signature:
      '92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69d' +
      'a085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00'
  },
  {
    privateKey:
      'c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7',
    publicKey:
      'fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025',
    message:
      'af82',
    signature:
      '6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3a' +
      'c18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a'
  },
  {
    privateKey:
      '8ed7a797b9cea8a8370d419136bcdf683b759d2e3c6947f17e13e2485aa9d420',
    publicKey:
      'b49f3a78b1c6a7fca8f3466f33bc0e929f01fba04306c2a7465f46c3759316d9',
    message:
      'a750c232933dc14b1184d86d8b4ce72e16d69744ba69818b6ac33b1d823bb2c3',
    signature:
      '04266c033b91c1322ceb3446c901ffcf3cc40c4034e887c9597ca1893ba7330' +
      'becbbd8b48142ef35c012c6ba51a66df9308cb6268ad6b1e4b03e70102495790b'
  }
];

function testPublicData() {
  goog.array.forEach(TEST_VECTORS,
    function(vector) {
      var keyPair = {
        'privKey': goog.crypt.hexToByteArray(vector.privateKey),
        'pubKey': goog.crypt.hexToByteArray(vector.publicKey)
      };
      var message = goog.crypt.hexToByteArray(vector.message);
      var expectedSignature = goog.crypt.hexToByteArray(vector.signature);
      var ecdsa = new e2e.ecc.Ed25519(
        e2e.ecc.PrimeCurve.ED_25519, keyPair);

      var signature = ecdsa.sign(message);
      assertArrayEquals(expectedSignature, signature);

      assertTrue(ecdsa.verify(message, signature));

      // Make sure the verification fails if we change one byte of the signature
      var badSignature = signature.slice(0);
      badSignature[1] = (badSignature[1] + 1) & 0xFF;
      assertFalse(ecdsa.verify(message, badSignature));

      // Make sure the verification fails if we pass a different message.
      assertFalse(ecdsa.verify(message + ':', signature));
    });
}


function testRandomData() {
  var curve = e2e.ecc.PrimeCurve.ED_25519;
  for (var i = 0; i < 10; i++) {
    var keyPair = e2e.ecc.Protocol.generateKeyPair(curve);
    var ecdsa = new e2e.ecc.Ed25519(curve, keyPair);
    var message = e2e.random.getRandomBytes(1000);

    var signature = ecdsa.sign(message);
    assertTrue(ecdsa.verify(message, signature));

    message[0] ^= 0x1;
    assertFalse(ecdsa.verify(message, signature));
    message[0] ^= 0x1;

    var index = e2e.random.getRandomBytes(1)[0] & 31;
    var xor = e2e.random.getRandomBytes(1, [0]);  // exclude 0
    signature[index] ^= xor;
    assertFalse(ecdsa.verify(message, signature));
  }
}
</script>
